package com.example.demo.controller;

import com.example.demo.common.Appvariable;
import com.example.demo.common.ResultAjax;
import com.example.demo.common.SessionUtils;
import com.example.demo.model.Articleinfo;
import com.example.demo.model.Userinfo;
import com.example.demo.model.vo.UserinfoVO;
import com.example.demo.service.ArticleService;
import com.example.demo.service.ArticleService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: yyx
 * Date: 2023-11-05
 * Time: 14:32
 */
@RestController
@RequestMapping("/art")
public class ArticleController {
    private static final int _DESC_ = 120;


    @Autowired
    private ArticleService articleService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    private UserService userService;

    @RequestMapping("/mylist")
    public ResultAjax myList(HttpServletRequest request){
        Userinfo userinfo = SessionUtils.getUser(request);
        //1.校验判空
        if(userinfo == null){
            return ResultAjax.fail(-1,"请先登录!");
        }
        //2.根据已经登录的用户id查询用户的所有文章
        List<Articleinfo> list = articleService.getArtByUid(userinfo.getId());
        //将正文处理为简介
        if(list != null || list.size()>0){
            //文章里有东西
            //并发处理
            list.stream().parallel().forEach((art)->{
                if(art.getContent().length()>_DESC_){
                    art.setContent(art.getContent().substring(0,_DESC_));
                }
            });
        }
        //3.返回结果给前端,此时不需要判断列表是否为空,
        return ResultAjax.succ(list);
    }

    @RequestMapping("/del")
    public ResultAjax del(Integer aid,HttpServletRequest request){
        //1.校验参数
        if(aid == null||aid <=0){
            return ResultAjax.fail(-1,"非法参数!");
        }
        //2.获取当前登录的用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null){
            return ResultAjax.fail(-2,"请先登录!");
        }

        //3.判断文章归属人并删除用户底下的指定文章
        int result = articleService.del(aid, userinfo.getId());

        //4.返回结果
        return ResultAjax.succ(result);
    }

    @RequestMapping("/add")
    public ResultAjax add(Articleinfo articleinfo,HttpServletRequest request){
        //1.校验参数
        if(articleinfo==null || !StringUtils.hasLength(articleinfo.getTitle()) ||
            !StringUtils.hasLength(articleinfo.getContent())){
                return ResultAjax.fail(-1,"非法参数!");
        }

        //2.组装数据,将uid假如文章表中,文章必须设置作者!
        //2.5从session中取用户对象
        Userinfo userinfo = SessionUtils.getUser(request);
        if(userinfo == null){
            //未登录
            return ResultAjax.fail(-2,"请先登录!!");
        }
        //将session中的userinfo的id设置到articleinfo的uid中
        articleinfo.setUid(userinfo.getId());

        //3.将数据入库
        int result = articleService.add(articleinfo);

        //4.将结果返回给前端
        return ResultAjax.succ(result);
    }

    /*查询自己文章的详情
    */
    @RequestMapping("/update_init")
    public ResultAjax updataInit(Integer aid,HttpServletRequest request){
        //1.校验参数
        if(aid == null || aid <=0){
            return ResultAjax.fail(-1,"非法参数!");
        }
        //2.获取uid
        Userinfo userinfo = SessionUtils.getUser(request);
        //同步校验:
        if(userinfo == null){
            return ResultAjax.fail(-2,"请先登录!");
        }
        //3.查询文章并校验用户  写在SQL里
        Articleinfo articleinfo = articleService.getArtByidANDuid(aid, userinfo.getId());

        //4.文章结果返回
        return  ResultAjax.succ(articleinfo);

    }

    @RequestMapping("/update")
    public ResultAjax update(Articleinfo articleinfo,HttpServletRequest request){
        //1.参数校验
        if(articleinfo==null || !StringUtils.hasLength(articleinfo.getContent()) ||
                !StringUtils.hasLength(articleinfo.getTitle()) ||
                articleinfo.getId() == 0) {
            return ResultAjax.fail(-1,"非法参数!");
        }

        //2.获取用户信息
        Userinfo userinfo = SessionUtils.getUser(request);
        if(userinfo == null){
            return ResultAjax.fail(-2,"请先登录!!");
        }

        //2.5将uid设置到文章表中!!!!
        articleinfo.setUid(userinfo.getId());

        //3.更新数据库并校验用户
        int result = articleService.update(articleinfo);


        //4.返回数据给前端
        return ResultAjax.succ(result);
    }

    //文章详情页(无须校验身份,因为未登录也能查看文章详情!)
    @RequestMapping("/detail")
    public ResultAjax detail(Integer aid) throws ExecutionException, InterruptedException {
        //1.校验参数
        if(aid==null || aid <=0){
            return ResultAjax.fail(-1,"非法参数!");
        }

        //2.查询文章详情(不能用之前的select方法,因为那个有where uid=#{uid},校验身份了,这个不能校验身份,重新写)
        Articleinfo articleinfo = articleService.getDetailByid(aid);//每次得到返回值都要判断一下!!!
        if(articleinfo==null || articleinfo.getId()<=0){
            return ResultAjax.fail(-2,"请先登录!");
        }
        //3.在文章属性获取UID然后采用多线程的方式,分两步查找:1.用户发表的总文章数2.该篇文章的详情
        FutureTask<UserinfoVO> userTask = new FutureTask(()->{
            UserinfoVO userinfoVo = userService.getUserByid(articleinfo.getUid());
            return userinfoVo;
        });
        FutureTask<Integer> countTask = new FutureTask(()->{
            return articleService.getArtCountByUid(articleinfo.getUid());
        });
        taskExecutor.submit(userTask);
        taskExecutor.submit(countTask);

        //4.组装数据
        UserinfoVO userinfoVO = userTask.get();//阻塞任务直到执行完毕
        int artCount = countTask.get();//阻塞任务直到执行完毕

        userinfoVO.setArtCount(artCount);//这一步不要忘记!!!要组合数据的!!!!

        HashMap<String,Object> map = new HashMap<>();
        map.put("user",userinfoVO);
        map.put("art",articleinfo);//注意这里不是返回那个总文章数,要返回Articleinfo对象!

        //5.返回结果RA
        return ResultAjax.succ(map);
    }

    @RequestMapping("/increment_rcount")
    public ResultAjax increment_rcount(Integer aid){
        //1.校验参数
        if(aid == null || aid <=0){
            return ResultAjax.fail(-1,"参数有误!");
        }

        //2.更新数据库
        int result = articleService.increment(aid);


        //3.返回数据
        return ResultAjax.succ(result);
    }

    @RequestMapping("/getlistbypage")
    public ResultAjax getlistbypage(Integer psize,Integer pindex) throws ExecutionException, InterruptedException {
        //1.参数矫正
        if(psize == null || psize<=0){
            psize = 1;
        }
        if(pindex == null || pindex<=0){
            pindex = 2;
        }
        //2.并发执行两个任务:1.查文章详情2.查文章总数
        //offset = psize*(pindex - 1)  不要传给MySQL让它计算,索引会失效
        Integer finalPsize = psize;
        Integer finalPindex = pindex;
        //小心变量捕获
        FutureTask<List<Articleinfo>> listTask = new FutureTask<>(()->{
            int offset = finalPsize *(finalPindex - 1);
            return articleService.getListByPage(finalPsize,offset);
        });
        FutureTask<Integer> sizeTask = new FutureTask<>(()->{
            int totalCount = articleService.getArtCount();
            //向上取整:利用(总页数/每页条数->向上取整)eg:10条信息分三页要显示4页
            double sizeTemp = (totalCount*1.0)/(finalPsize*1.0);
            return (int)Math.ceil(sizeTemp);
        });
        taskExecutor.submit(listTask);
        taskExecutor.submit(sizeTask);

        List<Articleinfo> list = listTask.get();
        int size = sizeTask.get();
        //3.组装数据
        HashMap<String,Object> map = new HashMap<>();
        map.put("list",list);
        map.put("size",size);

        //4.返回结果
        return ResultAjax.succ(map);
    }



}
